package com.slmxz.tms.common.component;

import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.slmxz.tms.common.constant.SystemConstants;
import com.slmxz.tms.common.util.DateUtils;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author：albert
 * @Date：2024/10/14 20:41
 * 单号创建: 例如订单号，合同单号，对账单号等
 */
public class NoGeneratorService {
    private static final String NO_GENERATOR_PREFIX = "SLMZ:TMS:NO:"; //单号统一创建的前缀

    private static final ReentrantLock lock = new ReentrantLock();

    /**
     * 根据前缀生成不重复的单号
     * @param prefix
     * @return
     */
    public static String generatorNo(String prefix,int minValue) throws Exception{
        //根据yyMMdd获取当天的日期字符串
        String localDate = DateUtils.formatLocalDate();
        //组装redis中不同数据库表递增值的key
        String noKey = NO_GENERATOR_PREFIX + prefix + ":" + localDate;
        //如果在500ms内获取锁失败,则放弃继续加锁
        if (lock.tryLock(SystemConstants.TRY_LOCK_TIMEOUT, TimeUnit.MILLISECONDS)) {
            try {
                //通过redis的自增长获取递增值
                long incrVal = RedisService.incr(noKey,1);
                if(incrVal == 1L){
                    //每天初次获取值的时候
                    RedisService.expire(noKey,2 * 24 * 60 * 60); //当前创建主键的key只保存2天
                }
                //组合成指定数据库表当天唯一的主键
                return prefix + localDate + (minValue + incrVal);
            } finally {
                lock.unlock();
            }
        }
        Assert.isNull(null,"no generate failed!");
        return null;

    }

}
